package com.cloud.custom.workflow.command.rollback;

import java.util.Date;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext;

import com.cloud.custom.common.context.HumanSession;
import com.cloud.custom.common.exception.BizException;
import com.cloud.custom.common.utils.DateHelper;
import com.cloud.custom.common.utils.SessionHelper;
import com.cloud.custom.interfaces.FeignClientFreeflow;
import com.cloud.custom.workflow.bean.WfActDef;
import com.cloud.custom.workflow.command.Command;
import com.cloud.custom.workflow.command.WfRequest;
import com.cloud.custom.workflow.command.WfResponse;
import com.cloud.custom.workflow.entity.WfActInst;
import com.cloud.custom.workflow.entity.WfItemInst;
import com.cloud.custom.workflow.entity.WfPerPart;
import com.cloud.custom.workflow.entity.WfTransInst;
import com.cloud.custom.workflow.enums.WfActStateEnum;
import com.cloud.custom.workflow.enums.WfItemTypeEnum;
import com.cloud.custom.workflow.enums.WfPartEnum;
import com.cloud.custom.workflow.mapper.WfActInstMapper;
import com.cloud.custom.workflow.mapper.WfItemInstMapper;
import com.cloud.custom.workflow.mapper.WfPerPartMapper;
import com.cloud.custom.workflow.mapper.WfTransInstMapper;

import tk.mybatis.mapper.entity.Example;

/**
 * 回退指令
 * 
 * @author Minglong.tao
 *
 */
public class RollbackCommand extends Command {

	@Override
	public void execute(WfRequest request, WfResponse resp, ApplicationContext context) {
		RollbackRequest roolbackReq = (RollbackRequest) request;
		HumanSession humanSession = SessionHelper.get();

		FeignClientFreeflow feignClientFreeFlow = context.getBean(FeignClientFreeflow.class);
		WfActDef nextActDef = feignClientFreeFlow.loadProcActDef(roolbackReq.getRollbackActDefId());

		// 更新当前环节的流程实例
		WfActInstMapper wfActInstMapper = context.getBean(WfActInstMapper.class);
		Example example = new Example(WfActInst.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("actId", roolbackReq.getActId());
		criteria.andEqualTo("actStateId", WfActStateEnum.PENDING.getActStateId());
		List<WfActInst> actInsts = wfActInstMapper.selectByExample(example);
		if (null == actInsts || actInsts.size() == 0) {
			throw new BizException(500, "流程实例不存在，请检查案卷是否已经批转");
		}
		WfActInst actInst = actInsts.get(0);
		actInst.setActStateId(WfActStateEnum.PROCESSED.getActStateId());
		actInst.setActStateName(WfActStateEnum.PROCESSED.getActStateName());
		actInst.setExpendTime(DateHelper.getMinutesBetween(actInst.getCreateTime(), new Date()));
		actInst.setExpendTimeChar(DateHelper.getTimeCharOfMinutes(actInst.getExpendTime()));
		wfActInstMapper.updateByPrimaryKey(actInst);

		// 增加最新环节的流程实例
		WfActInst currentActInst = new WfActInst();
		BeanUtils.copyProperties(nextActDef, currentActInst);
		currentActInst.setPerActDefId(actInst.getActDefId());
		currentActInst.setPerActId(actInst.getActId());
		currentActInst.setPartId(roolbackReq.getRollbackPartId());
		currentActInst.setPartName(roolbackReq.getRollbackPartName());
		currentActInst.setCreateTime(new Date());
		currentActInst.setPartType(WfPartEnum.HUMAN.getPartType());
		currentActInst.setPerHumanId(actInst.getPartId());
		currentActInst.setPerHumanName(actInst.getPartName());
		currentActInst.setRecId(roolbackReq.getRecId());
		currentActInst.setOpinion(roolbackReq.getOpinion());
		currentActInst.setActStateId(WfActStateEnum.PENDING.getActStateId());
		currentActInst.setActStateName(WfActStateEnum.PENDING.getActStateName());
		wfActInstMapper.insert(currentActInst);

		// 添加当前环节的经办人
		WfPerPartMapper wfPerPartMapper = context.getBean(WfPerPartMapper.class);
		WfPerPart perPart = new WfPerPart();
		perPart.setHumanId(humanSession.getHumanId());
		perPart.setRecId(roolbackReq.getRecId());
		if (!wfPerPartMapper.existsWithPrimaryKey(perPart)) {
			wfPerPartMapper.insert(perPart);
		}

		// 添加当前环节的工作项
		WfItemInstMapper wfItemInstMapper = context.getBean(WfItemInstMapper.class);
		WfItemInst itemInst = new WfItemInst();
		itemInst.setActId(currentActInst.getActId());
		itemInst.setActDefId(actInst.getActDefId());
		itemInst.setActDefName(actInst.getActDefName());
		itemInst.setActionTime(new Date());
		itemInst.setActionName("回退");
		itemInst.setDetail(humanSession.getHumanName() + "在" + actInst.getActDefName() + "阶段执行回退");
		itemInst.setItemContent(roolbackReq.getOpinion());
		itemInst.setHumanId(humanSession.getHumanId());
		itemInst.setHumanName(humanSession.getHumanName());
		itemInst.setItemTypeId(WfItemTypeEnum.TRANSIT.getItemTypeId());
		itemInst.setItemTypeName(WfItemTypeEnum.TRANSIT.getItemTypeName());
		itemInst.setRecId(roolbackReq.getRecId());
		wfItemInstMapper.insert(itemInst);

		// 添加当前环节流向实例
		WfTransInstMapper wfTransInstMapper = context.getBean(WfTransInstMapper.class);
		WfTransInst transInst = new WfTransInst();
		transInst.setTransDefId(roolbackReq.getTransDefId());
		transInst.setFromActDefName(actInst.getActDefName());
		transInst.setFromActDefId(actInst.getActDefId());
		transInst.setFromActId(actInst.getActId());
		transInst.setToActId(currentActInst.getActId());
		transInst.setToActDefId(currentActInst.getActDefId());
		transInst.setToActDefName(currentActInst.getActDefName());
		transInst.setNextPartId(currentActInst.getPartId());
		transInst.setNextPartName(currentActInst.getPartName());
		transInst.setNextPartType(currentActInst.getPartType());
		transInst.setCreateTime(new Date());
		transInst.setHumanId(humanSession.getHumanId());
		transInst.setHumanName(humanSession.getHumanName());
		transInst.setItemTypeId(WfItemTypeEnum.ROLLBACK.getItemTypeId());
		transInst.setItemTypeName(WfItemTypeEnum.ROLLBACK.getItemTypeName());
		transInst.setRecId(roolbackReq.getRecId());
		wfTransInstMapper.insert(transInst);
		// 更新上一环节的工作项目
		Example itemExample = new Example(WfItemInst.class);
		Example.Criteria itemCriteria = itemExample.createCriteria();
		itemCriteria.andEqualTo("recId", roolbackReq.getRecId());
		itemCriteria.andEqualTo("actId", actInst.getActId());
		List<WfItemInst> insts = wfItemInstMapper.selectByExample(itemExample);
		if (null != insts && insts.size() == 1) {
			WfItemInst inst = insts.get(0);
			inst.setNextActId(currentActInst.getActId());
			inst.setNextActDefId(roolbackReq.getRollbackActDefId() + "");
			inst.setNextActDefName(roolbackReq.getRollbackActDefName());
			inst.setNextPartId(roolbackReq.getRollbackPartId() + "");
			inst.setNextPartName(roolbackReq.getRollbackPartName());
			inst.setNextPartType(WfPartEnum.HUMAN.getPartType());
			wfItemInstMapper.updateByPrimaryKey(inst);
		}
		
		
		RollbackResponse rollbackResp = (RollbackResponse) resp;
		rollbackResp.setRecId(roolbackReq.getRecId());
		rollbackResp.setActId(currentActInst.getActId());
		rollbackResp.setActDef(nextActDef);
	}

}
